package com.um.springboot.starter.exception;

import com.um.springboot.starter.code.ValidatorCode;
import com.um.springboot.starter.orm.entity.Response;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;

/**
 * 参数校验异常信息返回
 * @author renjunwei
 * @date 2020/9/19 09:37
 */
@Order(1)
@ControllerAdvice
public class ValidatorExceptionHandler {

    /**
     * 参数不合法异常
     * 类注解：@Validated
     **/
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public Response constrainViolationHandler(ConstraintViolationException e) {
        ConstraintViolation violation = e.getConstraintViolations().stream().findFirst().get();
        String path = violation.getPropertyPath().toString();
        String field = path.substring(path.lastIndexOf('.') + 1);
        return Response.failed(ValidatorCode.ParamsIllegal, String.format("[%s]%s", field, violation.getMessage()));
    }

    /**
     * 参数不合法异常
     * 方法注解：@Valid @RequestBody
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Response validExceptionHandler(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        FieldError fieldError = bindingResult.getFieldErrors().stream().findFirst().get();
        return Response.failed(ValidatorCode.ParamsIllegal, String.format("[%s]%s", fieldError.getField(), fieldError.getDefaultMessage()));
    }

    /**
     * 参数不合法异常
     * 方法注解：@Valid @ModelAttribute
     **/
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Response bindExceptionHandler(BindException e) {
        FieldError fieldError = e.getFieldErrors().stream().findFirst().get();
        return Response.failed(ValidatorCode.ParamsIllegal, String.format("[%s]%s", fieldError.getField(), fieldError.getDefaultMessage()));
    }

    /**
     * POST参数序列化失败
     **/
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public Response httpMessageNotReadableHandler(HttpMessageNotReadableException e) {
        return Response.failed(ValidatorCode.ParamsIllegal, e.getMessage());
    }

    /**
     * 请求方式不正确
     **/
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public Response httpRequestMethodNotSupportedHandler(HttpRequestMethodNotSupportedException e) {
        return Response.failed(ValidatorCode.RequestMethodError);
    }

    /**
     * 缺少参数异常
     **/
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    public Response missingServletRequestParameterHandler(MissingServletRequestParameterException e) {
        return Response.failed(ValidatorCode.ParamsIllegal, String.format("缺少参数[%s]", e.getParameterName()));
    }

}
